package com.scrcu.cloud.wechat.home.endpoint.customer.service.Iml;

import com.alibaba.fastjson.JSONObject;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.scrcu.cloud.wechat.home.endpoint.common.model.RestResponse;
import com.scrcu.cloud.wechat.home.endpoint.common.utils.HttpUtils;
import com.scrcu.cloud.wechat.home.endpoint.customer.entity.UserInfo;
import com.scrcu.cloud.wechat.home.endpoint.customer.mapper.AppInfoMapper;
import com.scrcu.cloud.wechat.home.endpoint.customer.mapper.UserMapper;
import com.scrcu.cloud.wechat.home.endpoint.customer.service.IUserService;
import com.scrcu.cloud.wechat.home.endpoint.staff.utils.Util;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Map;


@Service
@Slf4j
public class UserServiceIml extends ServiceImpl<UserMapper, UserInfo> implements IUserService {

    //小程序配置
    @Value("${tencent.openid.requestUrl}")
    private String openid_reUrl;
    @Value("${tencent.grantType}")
    private String grantType;
    @Value("${default.tencent.appid}")
    private String defaultAppId;
    @Value("${default.tencent.secret}")
    private String defaultSecret;

    @Value("${tencent.access.token.url}")
    private String accessTokenUrl;
    @Value("${tencent.access.token.grantType}")
    private String tokenGrantType;

    @Value("${tencent.userinfo.url}")
    private String userinfo_url;
    @Value("${tencent.userinfo.grantType}")
    private String userinfoGrantType;

    @Value("${tencent.userPhone.url}")
    private String userphone_url;

    //代理配置
    @Value("${proxy.proxyStr}")
    private String proxyStr;
    @Value("${proxy.proxyPort}")
    private int proxyPort;

    @Autowired
    private AppInfoMapper appInfoMapper;

    @Override
    public RestResponse getOpenid(String code, String appid) {
        log.info("取得的code>"+code);
        log.info("取得的appid>"+appid);
        String secret = null;
        try{
            if (appid==null||appid.equalsIgnoreCase("null")||appid.length()==0){
                appid = defaultAppId;
                secret = appInfoMapper.getSecret(defaultAppId);
            }else{
                secret = appInfoMapper.getSecret(appid);
            }
        }catch(Exception e){
            e.printStackTrace();
            log.error("取得的secret出错");
            return RestResponse.failed("取得的secret出错, appid> "+appid);
        }

//        String url = openid_reUrl+"?js_code="+code+"&appid="+appid+"&secret="+secret+"&grantType="+grantType;
        String returnJson = null;
        Map<String,String> res = new HashMap<>();
        log.info("访问腾讯服务器的url："+openid_reUrl);

        try {
//            returnJson = Http_tool.wechatHttpSendGet(proxyStr,proxyPort,url).toJSONString();
//            returnJson = HttpUtils.builder(true)
//                    .url(openid_reUrl)
//                    .addParam("js_code",code)
//                    .addParam("appid", appid)
//                    .addParam("secret", secret)
//                    .addParam("grantType", grantType)
//                    .get()
//                    .execute();
            returnJson = HttpUtils.builder()
                .url(openid_reUrl)
                    .addParam("js_code",code)
                    .addParam("appid", appid)
                    .addParam("secret", secret)
                    .addParam("grantType", grantType)
                .get()
                .execute();
//            log.info("请求格式: "+url);
            log.info("访问腾讯服务器的返回报文："+returnJson);
            //            {"errcode":40029,"errmsg":"invalid code, rid: 6594c8ac-10e49791-47ffecdf"}

            String openid =String.valueOf(JSONObject.parseObject(returnJson).get("openid"));
            if (openid==null|| openid.equalsIgnoreCase("null")){
                log.error("openid错误");
                return RestResponse.failed("openid错误");
            }

            res.put("openid",openid);

        } catch (Throwable e) {
            e.printStackTrace();
            log.error("获取openid失败");
            return RestResponse.failed("获取openid失败");
        }
        log.info("该用户的openid为："+res);
        return RestResponse.success(res);
    }

    @Override
    public RestResponse getToken(String appid) {
        String secret = null;
        String returnJson = null;
        Map<String,String> res = new HashMap<>();
        try{
            if (appid==null||appid.equalsIgnoreCase("null")||appid.length()==0){
                appid = defaultAppId;
                secret = appInfoMapper.getSecret(defaultAppId);
            }else{
                secret = appInfoMapper.getSecret(appid);
            }
        }catch(Exception e){
            e.printStackTrace();
            log.error("取得的secret出错");
            return RestResponse.failed("取得的secret出错, appid> "+appid);
        }

        try{
            returnJson = HttpUtils.builder()
                    .url(accessTokenUrl)
                    .addParam("appid", appid)
                    .addParam("secret", secret)
                    .addParam("grant_type", tokenGrantType)
                    .get()
                    .execute();
        }catch (Exception e){
            log.error("请求access token出错");
            e.printStackTrace();
        }

        String access_token =String.valueOf(JSONObject.parseObject(returnJson).get("access_token"));
        if (access_token==null|| access_token.equalsIgnoreCase("null")){
            log.error("access_token错误");
            return RestResponse.failed("access_token错误");
        }
        log.info("获取到的token为>"+access_token);
        res.put("token",access_token);
        return RestResponse.success(res);
    }

    @Override
    public RestResponse getUserInfo(String code, String appid) {
        HashMap<String,String> map = null;
        String returnJson = null;
        Map<String,String> res = new HashMap<>();
        try{
            if (appid==null||appid.equalsIgnoreCase("null")||appid.length()==0){
                appid = defaultAppId;
            }
            map = appInfoMapper.getSecret4Multi(appid);
        }catch(Exception e){
            e.printStackTrace();
            log.error("取得的secret和应用id出错");
            return RestResponse.failed("取得的secret和应用id出错, appid为> "+appid);
        }
        log.info("map>"+map.toString());
        String secret = map.get("app_secret");
        String application_id = map.get("application_id");
        try{
            returnJson = HttpUtils.builder()
                    .url(userinfo_url)
                    .addParam("appid", application_id)
                    .addParam("appsecret", secret)
                    .addParam("code", code)
                    .addParam("grant_type", userinfoGrantType)
                    .get()
                    .execute();
        }catch (Exception e){
            log.error("请求access token出错");
            e.printStackTrace();
        }
        log.info("returnJson>"+returnJson);
        try{
            String login_info_str =String.valueOf(JSONObject.parseObject(returnJson).get("login_info"));
            String user_info_str =String.valueOf(JSONObject.parseObject(returnJson).get("user_info"));
            log.info(login_info_str);
            log.info(user_info_str);
            //登录信息
            String loginTime = String.valueOf(JSONObject.parseObject(login_info_str).get("login_time"));
            String type = String.valueOf(JSONObject.parseObject(login_info_str).get("type"));
            //登录方式: weixinApp, weixinMiniProgram, phoneSms, apple, phoneOneClick

            //用户标识信息 user_info
            String user_id = String.valueOf(JSONObject.parseObject(user_info_str).get("user_id"));
            String phone_info;
            String phonenum;
            String miniprogram_info;
            String apple_info;
            res.put("user_id",user_id);
            switch (type){
                case "weixinApp":  //微信移动应用信息 openapp_info
                    String openapp_info = String.valueOf(JSONObject.parseObject(user_info_str).get("openapp_info"));

                    String weixinAppappid = String.valueOf(JSONObject.parseObject(openapp_info).get("appid"));
                    String weixinAppopenid = String.valueOf(JSONObject.parseObject(openapp_info).get("openid"));
                    String weixinAppunionid = String.valueOf(JSONObject.parseObject(openapp_info).get("unionid"));
                    String weixinAppheadimgurl = String.valueOf(JSONObject.parseObject(openapp_info).get("headimgurl"));
                    String weixinAppnickname = String.valueOf(JSONObject.parseObject(openapp_info).get("nickname"));
                    log.info("weixinApp>"+openapp_info);
                    break;
                case "weixinMiniProgram":
                    miniprogram_info = String.valueOf(JSONObject.parseObject(user_info_str).get("miniprogram_info"));

                    String weixinMiniProgramappid = String.valueOf(JSONObject.parseObject(miniprogram_info).get("appid"));
                    String weixinMiniProgramopenid = String.valueOf(JSONObject.parseObject(miniprogram_info).get("openid"));
                    String weixinMiniProgramunionid = String.valueOf(JSONObject.parseObject(miniprogram_info).get("unionid"));
                    log.info("weixinMiniProgram>"+miniprogram_info);
                    break;
                case "phoneSms":
                    phone_info = String.valueOf(JSONObject.parseObject(user_info_str).get("phone_info"));
                    phonenum = String.valueOf(JSONObject.parseObject(phone_info).get("phone"));
                    res.put("phonenum",phonenum);
                    log.info("phoneSms>"+phone_info);
                    break;
                case "phoneOneClick":
                    phone_info = String.valueOf(JSONObject.parseObject(user_info_str).get("phone_info"));
                    phonenum = String.valueOf(JSONObject.parseObject(phone_info).get("phone"));
                    res.put("phonenum",phonenum);
                    log.info("phoneOneClick>"+phone_info);
                    break;
                case "apple":
                    apple_info = String.valueOf(JSONObject.parseObject(user_info_str).get("apple_info"));

                    String bundleid = String.valueOf(JSONObject.parseObject(apple_info).get("bundleid"));
                    String apple_user_id = String.valueOf(JSONObject.parseObject(apple_info).get("apple_user_id"));
                    log.info("apple>"+apple_info);
                    break;
                default:
                    break;
            }
            log.info(res.toString());
            return RestResponse.success(res);
        }catch (Exception e){
            e.printStackTrace();
            log.error("解析结果失败");
            return RestResponse.failed("解析结果失败");
        }




//        if (login_info==null|| login_info.equalsIgnoreCase("null")){
//            log.error("access_token错误");
//            return RestResponse.failed("access_token错误");
//        }
//        log.info("获取到的token为>"+access_token);
//        res.put("token",access_token);


    }

    @Override
    public RestResponse getPhoneInfo(String code, String token) {
        String realUrl = userphone_url+token;
        String returnJson = null;
        try {
            returnJson = HttpUtils.builder()
                    .url(realUrl)
                    .addParam("code", code)
                    .post()
                    .execute();
        }catch (Exception e){
            e.printStackTrace();
            log.error("请求手机号出错");
        }
        Map<String,String> res = new HashMap<>();
        String phone_info = String.valueOf(JSONObject.parseObject(returnJson).get("phone_info"));

        String purePhoneNumber = String.valueOf(JSONObject.parseObject(phone_info).get("purePhoneNumber"));
        String countryCode = String.valueOf(JSONObject.parseObject(phone_info).get("countryCode"));
        res.put("purePhoneNumber",purePhoneNumber);
        res.put("countryCode",countryCode);

        return RestResponse.success(res);
    }

    @Override
    public RestResponse judgeUser(String openid, String last_login_location) {
        UserInfo userInfo = getBaseMapper().selectById(openid);
        HashMap<String,Object> res = new HashMap<>();

        if (userInfo==null){
            log.info("没有查到该用户，请登录");
            res.put("successcode","0000");
            return RestResponse.success(res);
        }else{
            log.info("已有该用户，开始获取用户信息......");
            userInfo.setLastLoginLocation(last_login_location);
            int uflag = this.getBaseMapper().updateById(userInfo);
            if (uflag>=1){
                log.info("已更新用户最新登录位置");
            }else{
                log.error("更新用户最新登录位置失败");
            }
            res.put("successcode","0001");
            res.put("userinfo", userInfo);
            return RestResponse.success(res);
        }

    }

    @Override
    public RestResponse registerUser(String uname, String telnum, String idcard,
                                     String openid, String registerLocation) {
        HashMap<String,Object> res = new HashMap<>();
        UserInfo quser = this.getBaseMapper().selectById(openid);
        if (quser!=null){
            log.info("已有用户, user>"+quser);
            log.info("开始更新用户信息................>");
            quser.setTelnum(telnum);
            quser.setLastLoginLocation(registerLocation);
            int uflag = this.getBaseMapper().updateById(quser);
            if (uflag>=1)
                log.info("更新用户信息完成................>");
            res.put("userInfo",quser);
            return RestResponse.success(res);
        }

        UserInfo userInfo = new UserInfo();
        userInfo.setUname(uname);
        if (uname == null || uname.length() == 0)
            userInfo.setUname("匿名用户");
        userInfo.setTelnum(telnum);
        userInfo.setUid(openid);
        userInfo.setOpenId(openid);
        userInfo.setIdcard(idcard);
        if (idcard == null || idcard.length() == 0)
            userInfo.setIdcard("");
        userInfo.setRegisterLocation(registerLocation);
        userInfo.setLastLoginLocation(registerLocation);
//        DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm:ss");
        LocalDateTime createDate = LocalDateTime.now();
        userInfo.setRegisterTime(createDate);

        int iflag = this.getBaseMapper().insert(userInfo);
        if (iflag>=1){
            log.info("新增用户信息成功, user>"+userInfo);
            res.put("userInfo",userInfo);
            return RestResponse.success(res);
        }else{
            log.info("新增用户信息失败");
            return RestResponse.failed("新增用户信息失败");
        }
    }

    @Override
    public RestResponse getMyInfo(String openid) {
        UserInfo user = getBaseMapper().selectById(openid);
        if (user!=null){
            return RestResponse.success(user);
        }
        return RestResponse.failed("用户信息获取失败");
    }

    @Override
    public RestResponse changeMyInfo(String openid, Integer todoType, String value) {
        UserInfo user = getBaseMapper().selectById(openid);
        if (user==null){
            return RestResponse.failed("没有该用户");
        }
        switch (todoType){
            case 0: //修改姓名
                if (value!=null&&value.length()>1){
                    user.setUname(value);
                }else{
                    return RestResponse.failed("姓名输入错误");
                }
                break;
            case 1: //修改手机号
                if (value!=null&& Util.isNumeric(value)){
                    user.setTelnum(value);
                }else{
                    return RestResponse.failed("格式错误");
                }
                break;
            case 2: //修改性别
                if (value!=null&&value.length()>0&&value.length()<3){
                    user.setGender(value);
                }else{
                    return RestResponse.failed("格式错误");
                }
                break;
            case 3: //修改身份证
                if (value!=null&& Util.isNumeric(value)){
                    user.setIdcard(value);
                }else{
                    return RestResponse.failed("格式错误");
                }
                break;
            case 4: //城市和地区信息修改
                if (value != null && value.contains("-")){
                    String[] list = value.split("-");
                    if (list.length==2){
                        user.setCity(list[0]);
                        user.setArea(list[1]);
                    }
                }
                break;
            default:
                break;
        }
        int uflag = getBaseMapper().updateById(user);
        if (uflag>=1){
            return RestResponse.success(user);
        }
        return RestResponse.failed("更新失败");
    }
}
